home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / ixemul-complete / ixemul / ixnet / socket.c < prev    next >
C/C++ Source or Header  |  1996-08-13  |  19KB  |  819 lines

  1. /*
  2.  *  This file is part of ixnet.library for the Amiga.
  3.  *  Copyright (C) 1996 by Jeff Shepherd
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  $Id:$
  20.  *
  21.  *  $Log:$
  22.  *
  23.  */
  24.  
  25. #define _KERNEL
  26. #include "ixnet.h"
  27.  
  28. #include <sys/socket.h>
  29. #include <sys/socketvar.h>
  30. #include <sys/ioctl.h>
  31. #include <net/if.h>
  32. #include <net/route.h>
  33. #include <netinet/in.h>
  34. #include <machine/param.h>
  35. #include <string.h>
  36. #include <inetd.h>
  37. #include <stdlib.h>
  38. #include "select.h"
  39. #include "ixprotos.h"
  40.  
  41. int _tcp_read    (struct file *fp, char *buf, int len);
  42. int _tcp_write    (struct file *fp, char *buf, int len);
  43. int _tcp_ioctl    (struct file *fp, int cmd, int inout, int arglen, caddr_t data);
  44. int _tcp_select (struct file *fp, int select_cmd, int io_mode, fd_set *, u_long *);
  45. int _tcp_close    (struct file *fp);
  46.  
  47. int
  48. _socket (int domain, int type, int protocol)
  49. {
  50.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  51.     register int network_protocol = p->u_networkprotocol;
  52.     int err = -1;
  53.  
  54.     switch (network_protocol) {
  55.     case IX_NETWORK_AS225:
  56.         err = SOCK_socket(domain, type, protocol);
  57.     break;
  58.  
  59.     case IX_NETWORK_AMITCP:
  60.         err = TCP_Socket(domain, type, protocol);
  61.     break;
  62.     }
  63.     return err;
  64. }
  65.  
  66.  
  67. int
  68. _bind (struct file *fp, const struct sockaddr *name, int namelen)
  69. {
  70.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  71.     register int network_protocol = p->u_networkprotocol;
  72.     int error = -1;
  73.  
  74.     switch (network_protocol) {
  75.     case IX_NETWORK_AS225:
  76.         error = SOCK_bind(fp->f_so, name, namelen);
  77.     break;
  78.  
  79.     case IX_NETWORK_AMITCP:
  80.         error = TCP_Bind(fp->f_so, name, namelen);
  81.     break;
  82.     }
  83.     return error;
  84. }
  85.  
  86. int
  87. _listen (struct file *fp, int backlog)
  88. {
  89.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  90.     register int network_protocol = p->u_networkprotocol;
  91.     int error = -1;
  92.  
  93.     switch (network_protocol) {
  94.     case IX_NETWORK_AS225:
  95.         error = SOCK_listen(fp->f_so, backlog);
  96.     break;
  97.  
  98.     case IX_NETWORK_AMITCP:
  99.         error = TCP_Listen(fp->f_so, backlog);
  100.     break;
  101.     }
  102.     return error;
  103. }
  104.  
  105. int
  106. _accept (struct file *fp, struct sockaddr *name, int *namelen)
  107. {
  108.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  109.     register int network_protocol = p->u_networkprotocol;
  110.     int err = -1;
  111.     switch (network_protocol) {
  112.     case IX_NETWORK_AS225:
  113.         err = SOCK_accept(fp->f_so, name, namelen);
  114.     break;
  115.  
  116.     case IX_NETWORK_AMITCP:
  117.         err = TCP_Accept(fp->f_so, name, namelen);
  118.     break;
  119.     }
  120.     return err;
  121. }
  122.  
  123.  
  124. int
  125. _connect (struct file *fp, const struct sockaddr *name, int namelen)
  126. {
  127.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  128.     register int network_protocol = p->u_networkprotocol;
  129.     int error = -1;
  130.     switch (network_protocol) {
  131.     case IX_NETWORK_AS225:
  132.         error = SOCK_connect(fp->f_so, name,namelen);
  133.     break;
  134.  
  135.     case IX_NETWORK_AMITCP:
  136.         error = TCP_Connect(fp->f_so, name,namelen);
  137.     break;
  138.     }
  139.     return error;
  140. }
  141.  
  142. int
  143. _sendto (struct file *fp, const void *buf, int len, int flags, const struct sockaddr *to, int tolen)
  144. {
  145.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  146.     register int network_protocol = p->u_networkprotocol;
  147.     int rc = -1;
  148.  
  149.     switch (network_protocol) {
  150.  
  151.     case IX_NETWORK_AS225:
  152.         rc = SOCK_sendto(fp->f_so,buf,len,flags,to,tolen);
  153.     break;
  154.  
  155.     case IX_NETWORK_AMITCP:
  156.         rc = TCP_SendTo(fp->f_so,buf,len,flags,to,tolen);
  157.     break;
  158.     }
  159.  
  160.     return rc;
  161. }
  162.  
  163.  
  164. int
  165. _send (struct file *fp, const void *buf, int len, int flags)
  166. {
  167.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  168.     register int network_protocol = p->u_networkprotocol;
  169.     int rc = -1 ;
  170.  
  171.     switch (network_protocol) {
  172.  
  173.     case IX_NETWORK_AS225:
  174.         rc = SOCK_send(fp->f_so,buf,len,flags);
  175.     break;
  176.  
  177.     case IX_NETWORK_AMITCP:
  178.         rc = TCP_Send(fp->f_so,buf,len,flags);
  179.     break;
  180.     }
  181.  
  182.     return rc;
  183. }
  184.  
  185.  
  186. int
  187. _sendmsg (struct file *fp, const struct msghdr *msg, int flags)
  188. {
  189.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  190.     register int network_protocol = p->u_networkprotocol;
  191.     int rc = -1;
  192.  
  193.     switch (network_protocol) {
  194.  
  195.     case IX_NETWORK_AS225:
  196.         rc = SOCK_sendmsg(fp->f_so,msg,flags);
  197.     break;
  198.  
  199.     case IX_NETWORK_AMITCP:
  200.         rc = TCP_SendMsg(fp->f_so,msg,flags);
  201.     break;
  202.     }
  203.  
  204.     return rc;
  205. }
  206.  
  207.  
  208. int
  209. _recvfrom (struct file *fp, void *buf, int len, int flags, struct sockaddr *from, int *fromlen)
  210. {
  211.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  212.     register int network_protocol = p->u_networkprotocol;
  213.     int rc = -1;
  214.  
  215.     switch (network_protocol) {
  216.  
  217.     case IX_NETWORK_AS225:
  218.         rc = SOCK_recvfrom(fp->f_so,buf,len,flags, from, fromlen);
  219.     break;
  220.  
  221.     case IX_NETWORK_AMITCP:
  222.         rc = TCP_RecvFrom(fp->f_so,buf,len,flags, from, fromlen);
  223.     break;
  224.     }
  225.  
  226.     return rc;
  227. }
  228.  
  229.  
  230. int
  231. _recv (struct file *fp, void *buf, int len, int flags)
  232. {
  233.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  234.     register int network_protocol = p->u_networkprotocol;
  235.     int rc = -1;
  236.  
  237.     switch (network_protocol) {
  238.  
  239.     case IX_NETWORK_AS225:
  240.         rc = SOCK_recv(fp->f_so,buf,len,flags);
  241.     break;
  242.  
  243.     case IX_NETWORK_AMITCP:
  244.         rc = TCP_Recv(fp->f_so,buf,len,flags);
  245.     break;
  246.     }
  247.  
  248.     return rc;
  249. }
  250.  
  251.  
  252. int
  253. _recvmsg (struct file *fp, struct msghdr *msg, int flags)
  254. {
  255.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  256.     register int network_protocol = p->u_networkprotocol;
  257.     int rc = -1;
  258.  
  259.     switch (network_protocol) {
  260.  
  261.     case IX_NETWORK_AS225:
  262.         rc = SOCK_recvmsg(fp->f_so,msg,flags);
  263.     break;
  264.  
  265.     case IX_NETWORK_AMITCP:
  266.         rc = TCP_RecvMsg(fp->f_so,msg,flags);
  267.     break;
  268.     }
  269.  
  270.     return rc;
  271. }
  272.  
  273. int _socketpair(int d, int type, int protocol, int sv[2])
  274. {
  275.     errno = ENOSYS;
  276.     return -1;
  277. }
  278.  
  279. int
  280. _shutdown (struct file *fp, int how)
  281. {
  282.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  283.     register int network_protocol = p->u_networkprotocol;
  284.     int err = 0;
  285.  
  286.     switch (network_protocol) {
  287.  
  288.     case IX_NETWORK_AS225:
  289.         err = SOCK_shutdown(fp->f_so,how);
  290.     break;
  291.  
  292.     case IX_NETWORK_AMITCP:
  293.         err = TCP_ShutDown(fp->f_so,how);
  294.     break;
  295.     }
  296.     return err;
  297. }
  298.  
  299.  
  300. int
  301. _setsockopt (struct file *fp, int level, int name, const void *val, int valsize)
  302. {
  303.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  304.     register int network_protocol = p->u_networkprotocol;
  305.     int err = 0;
  306.  
  307.     switch (network_protocol) {
  308.  
  309.     case IX_NETWORK_AS225:
  310.         err = SOCK_setsockopt(fp->f_so,level,name,val, valsize);
  311.     break;
  312.  
  313.     case IX_NETWORK_AMITCP:
  314.         err = TCP_SetSockOpt(fp->f_so,level,name,val, valsize);
  315.     break;
  316.     }
  317.  
  318.     return err;
  319. }
  320.  
  321. int
  322. _getsockopt (struct file *fp, int level, int name, void *val, int *valsize)
  323. {
  324.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  325.     register int network_protocol = p->u_networkprotocol;
  326.     int err = 0;
  327.  
  328.     switch (network_protocol) {
  329.  
  330.     case IX_NETWORK_AS225:
  331.         err = SOCK_getsockopt(fp->f_so,level,name,val, valsize);
  332.     break;
  333.  
  334.     case IX_NETWORK_AMITCP:
  335.         err = TCP_GetSockOpt(fp->f_so,level,name,val, valsize);
  336.     break;
  337.     }
  338.  
  339.     return err;
  340. }
  341.  
  342.  
  343. /*
  344.  * Get socket name.
  345.  */
  346. int
  347. _getsockname (struct file *fp, struct sockaddr *asa, int *alen)
  348. {
  349.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  350.     register int network_protocol = p->u_networkprotocol;
  351.     int err = -1;
  352.  
  353.     switch (network_protocol) {
  354.  
  355.     case IX_NETWORK_AS225:
  356.         err = SOCK_getsockname(fp->f_so,asa,alen);
  357.     break;
  358.  
  359.     case IX_NETWORK_AMITCP:
  360.         err = TCP_GetSockName(fp->f_so,asa,alen);
  361.     break;
  362.     }
  363.  
  364.     return err;
  365. }
  366.  
  367. /*
  368.  * Get name of peer for connected socket.
  369.  */
  370. int
  371. _getpeername (struct file *fp, struct sockaddr *asa, int *alen)
  372. {
  373.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  374.     register int network_protocol = p->u_networkprotocol;
  375.     int err = -1;
  376.  
  377.     switch (network_protocol) {
  378.  
  379.     case IX_NETWORK_AS225:
  380.         err = SOCK_getpeername(fp->f_so,asa,alen);
  381.     break;
  382.  
  383.     case IX_NETWORK_AMITCP:
  384.         err = TCP_GetPeerName(fp->f_so,asa,alen);
  385.     break;
  386.     }
  387.  
  388.     return err;
  389. }
  390.  
  391. int
  392. _tcp_read (struct file *fp, char *buf, int len)
  393. {
  394.     int ostat, rc;
  395.     struct user *p = &u;
  396.  
  397.     ostat = p->p_stat;
  398.     p->p_stat = SWAIT;
  399.  
  400.     rc = _recv(fp,buf,len, 0);
  401.  
  402.     if (CURSIG (p))
  403.     SetSignal (0, SIGBREAKF_CTRL_C);
  404.  
  405.     p->p_stat = ostat;
  406.  
  407.     if (errno == EINTR)
  408.     setrun (FindTask (0));
  409.  
  410.     return rc;
  411. }
  412.  
  413.  
  414. int
  415. _tcp_write (struct file *fp, char *buf, int len)
  416. {
  417.     struct user *p = &u;
  418.     int ostat, rc;
  419.  
  420.     ostat = p->p_stat;
  421.     p->p_stat = SWAIT;
  422.  
  423.     rc = _send(fp,buf,len,0);
  424.  
  425.     if (CURSIG (p))
  426.     SetSignal (0, SIGBREAKF_CTRL_C);
  427.  
  428.     p->p_stat = ostat;
  429.  
  430.     if (errno == EINTR)
  431.     setrun (FindTask (0));
  432.  
  433.     return rc;
  434. }
  435.  
  436. int
  437. _tcp_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data)
  438. {
  439.     register struct user *usr = &u;
  440.     register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
  441.     register int network_protocol = p->u_networkprotocol;
  442.     int ostat, err = 0;
  443.  
  444.     ostat = usr->p_stat;
  445.     usr->p_stat = SWAIT;
  446.  
  447.     switch (network_protocol) {
  448.  
  449.     case IX_NETWORK_AS225:
  450.  
  451.         /* _SIGH_... they left almost everything neatly as it was in the BSD kernel
  452.          *    code they used, but for whatever reason they decided they needed their
  453.          *    own kind of ioctl encoding :-((
  454.          *
  455.          *    Well then, here we go, and map `normal' cmds into CBM cmds:
  456.          */
  457.  
  458.         switch (cmd) {
  459.         case SIOCADDRT         : cmd = ('r'<<8)|1; break;
  460.         case SIOCDELRT         : cmd = ('r'<<8)|2; break;
  461.         case SIOCSIFADDR     : cmd = ('i'<<8)|3; break;
  462.         case SIOCGIFADDR     : cmd = ('i'<<8)|4; break;
  463.         case SIOCSIFDSTADDR  : cmd = ('i'<<8)|5; break;
  464.         case SIOCGIFDSTADDR  : cmd = ('i'<<8)|6; break;
  465.         case SIOCSIFFLAGS    : cmd = ('i'<<8)|7; break;
  466.         case SIOCGIFFLAGS    : cmd = ('i'<<8)|8; break;
  467.         case SIOCGIFCONF     : cmd = ('i'<<8)|9; break;
  468.         case SIOCSIFMTU      : cmd = ('i'<<8)|10; break;
  469.         case SIOCGIFMTU      : cmd = ('i'<<8)|11; break;
  470.         case SIOCGIFBRDADDR  : cmd = ('i'<<8)|12; break;
  471.         case SIOCSIFBRDADDR  : cmd = ('i'<<8)|13; break;
  472.         case SIOCGIFNETMASK  : cmd = ('i'<<8)|14; break;
  473.         case SIOCSIFNETMASK  : cmd = ('i'<<8)|15; break;
  474.         case SIOCGIFMETRIC   : cmd = ('i'<<8)|16; break;
  475.         case SIOCSIFMETRIC   : cmd = ('i'<<8)|17; break;
  476.         case SIOCSARP         : cmd = ('i'<<8)|18; break;
  477.         case SIOCGARP         : cmd = ('i'<<8)|19; break;
  478.         case SIOCDARP         : cmd = ('i'<<8)|20; break;
  479.         case SIOCATMARK      : cmd = ('i'<<8)|21; break;
  480.         case FIONBIO         : cmd = ('m'<<8)|22; break;
  481.         case FIONREAD         : cmd = ('m'<<8)|23; break;
  482.         case FIOASYNC         : cmd = ('m'<<8)|24; break;
  483.         case SIOCSPGRP         : cmd = ('m'<<8)|25; break;
  484.         case SIOCGPGRP         : cmd = ('m'<<8)|26; break;
  485.  
  486.         default:
  487.         /* we really don't have to bother the library with cmds we can't even
  488.          * map over...
  489.          */
  490.         }
  491.         err = SOCK_ioctl(fp->f_so,cmd,data);
  492.     break;
  493.  
  494.     case IX_NETWORK_AMITCP:
  495.         err = TCP_IoctlSocket(fp->f_so,cmd,data);
  496.     break;
  497.     }
  498.     if (CURSIG (usr))
  499.     SetSignal (0, SIGBREAKF_CTRL_C);
  500.  
  501.     usr->p_stat = ostat;
  502.  
  503.     if (errno == EINTR)
  504.     setrun (FindTask (0));
  505.  
  506.     return err;
  507. }
  508.  
  509. /* looks like ixemul.library can't grog ixnet.library calling ix_lock_base()
  510.  * moved most of this code back into ixemul.library
  511.  */
  512. int
  513. _tcp_close (struct file *fp)
  514. {
  515.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  516.     register int network_protocol = p->u_networkprotocol;
  517.     int err = 0;
  518.  
  519. #if 0
  520.     ix_lock_base ();
  521.     fp->f_count--;
  522.  
  523.     if (fp->f_count == 0) {
  524.     /* don't have the base locked for IN_close, this MAY block!! */
  525.     ix_unlock_base ();
  526. #endif
  527.     switch (network_protocol) {
  528.  
  529.         case IX_NETWORK_AS225:
  530.         err = SOCK_close (fp->f_so);
  531.         break;
  532.  
  533.         case IX_NETWORK_AMITCP:
  534.         err = TCP_CloseSocket(fp->f_so);
  535.         break;
  536.     }
  537. #if 0
  538.     }
  539.     else
  540.     ix_unlock_base ();
  541. #endif
  542.     return err;
  543. }
  544.  
  545. static int
  546. _tcp_poll(struct file *fp, int io_mode)
  547. {
  548.     int rc = -1;
  549.     fd_set in, out, exc;
  550.     struct timeval tv = {0, 0};
  551.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  552.     register int network_protocol = p->u_networkprotocol;
  553.  
  554.     FD_ZERO(&in);
  555.     FD_ZERO(&out);
  556.     FD_ZERO(&exc);
  557.  
  558.     switch (io_mode) {
  559.     case SELMODE_IN:
  560.         FD_SET(fp->f_so,&in);
  561.     break;
  562.  
  563.     case SELMODE_OUT:
  564.         FD_SET(fp->f_so,&out);
  565.     break;
  566.  
  567.     case SELMODE_EXC:
  568.         FD_SET(fp->f_so,&exc);
  569.     break;
  570.     }
  571.  
  572.     switch (network_protocol) {
  573.     case IX_NETWORK_AS225:
  574.         rc = SOCK_selectwait(fp->f_so+1,&in,&out,&exc,&tv,NULL);
  575.     break;
  576.  
  577.     case IX_NETWORK_AMITCP:
  578.         rc = TCP_WaitSelect(fp->f_so+1,&in,&out,&exc,&tv,NULL);
  579.     break;
  580.     }
  581.  
  582.     return ((rc == 1) ? 1 : 0);
  583. }
  584.  
  585. int
  586. _tcp_select (struct file *fp, int select_cmd, int io_mode, fd_set *set, u_long *nfds)
  587. {
  588.   if (select_cmd == SELCMD_PREPARE)
  589.     {
  590.       register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  591.  
  592.       FD_SET(fp->f_so, set);
  593.       if (fp->f_so > *nfds)
  594.         *nfds = fp->f_so;
  595.       return (1L << p->u_sigurg | 1L << p->u_sigio);
  596.     }
  597.   if (select_cmd == SELCMD_CHECK)
  598.     return FD_ISSET(fp->f_so, set);
  599.   if (select_cmd == SELCMD_POLL)
  600.     return _tcp_poll(fp, io_mode);
  601.   return 0;
  602. }
  603.  
  604. u_long
  605. waitselect(long wait_sigs, fd_set *in, fd_set *out, fd_set *exc, u_long nfds)
  606. {
  607.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  608.     int rc = -1;
  609.  
  610.     switch (p->u_networkprotocol) {
  611.     case IX_NETWORK_AS225:
  612.         rc = SOCK_selectwait(nfds + 1, in, out, exc, NULL, &wait_sigs);
  613.     break;
  614.  
  615.     case IX_NETWORK_AMITCP:
  616.         rc = TCP_WaitSelect(nfds + 1, in, out, exc, NULL, &wait_sigs);
  617.     break;
  618.     }
  619.     return (rc == -1 ? -1 : wait_sigs);
  620. }
  621.  
  622. /*
  623.  *    init_inet_daemon.c - obtain socket accepted by the inetd
  624.  *
  625.  *    Copyright © 1994 AmiTCP/IP Group,
  626.  *             Network Solutions Development Inc.
  627.  *             All rights reserved.
  628.  *    Portions Copyright © 1995 by Jeff Shepherd
  629.  */
  630.  
  631. /* AS225 inet daemon stuff */
  632. struct inetmsg {
  633.     struct Message  msg;
  634.     ULONG   id;
  635. };
  636.  
  637. int
  638. init_inet_daemon(int *argc, char ***argv)
  639. {
  640.     register struct user *usr = &u;
  641.     register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
  642.     struct file *fp;
  643.     register int network_protocol = p->u_networkprotocol;
  644.     int sock;
  645.  
  646.     if (network_protocol == IX_NETWORK_AS225) {
  647.     static int init_d(int *, char ***);
  648.     return init_d(argc,argv);
  649.     }
  650.     else if (network_protocol == IX_NETWORK_AMITCP) {
  651.     struct Process *me = (struct Process *)SysBase->ThisTask;
  652.     struct DaemonMessage *dm = (struct DaemonMessage *)me->pr_ExitData;
  653.     int fd,ostat;
  654.     int err;
  655.  
  656.     if (dm == NULL) {
  657.         /*
  658.         * No DaemonMessage, return error code - probably not an inet daemon
  659.         */
  660.         return -1;
  661.     }
  662.  
  663.     /*
  664.      * Obtain the server socket
  665.      */
  666.     sock = TCP_ObtainSocket(dm->dm_Id, dm->dm_Family, dm->dm_Type, 0);
  667.     if (sock < 0) {
  668.         /*
  669.         * If ObtainSocket fails we need to exit with this specific exit code
  670.         * so that the inetd knows to clean things up
  671.         */
  672.         exit(DERR_OBTAIN);
  673.     }
  674.  
  675.     ostat = usr->p_stat;
  676.     usr->p_stat = SWAIT;
  677.  
  678.     do {
  679.  
  680.         if ((err = falloc(&fp, &fd)))
  681.         break;
  682.  
  683.         fp->f_so = sock;
  684.         _set_socket_params(fp,AF_INET);
  685.     } while (0);
  686.  
  687.     if (CURSIG (usr))
  688.         SetSignal (0, SIGBREAKF_CTRL_C);
  689.  
  690.     usr->p_stat = ostat;
  691.  
  692.     if (err == EINTR)
  693.         setrun (FindTask (0));
  694.  
  695.     errno = err;
  696.     return err ? -1 : fd;
  697.     }
  698.     else
  699.     return -1;
  700. }
  701.  
  702. /* code loosely derived from timed.c from AS225r2 */
  703. /* this program was called from inetd if :
  704.  * 1> the first arg is a valid protocol(call getprotobyname)
  705.  * 2> inetd is started - FindPort("inetd") returns non-NULL
  706.  * NOT 3> argv[0] is the program found in inetd.conf for the program (scan inetd.conf)
  707.  */
  708. #include <netdb.h>
  709. #include <stdio.h>
  710.  
  711. static int init_d(int *argc, char ***argv)
  712. {
  713.     struct user *usr = &u;
  714.     register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
  715.     int ostat;
  716.     int err = 1;
  717.     int fd = -1;
  718.  
  719.     ostat = usr->p_stat;
  720.     usr->p_stat = SWAIT;
  721.  
  722.     /* save a little time with this comparison */
  723.     if (*argc >= 4) {
  724.     struct servent *serv, *serv2;
  725.     serv = SOCK_getservbyname((*argv)[1],"tcp");
  726.     serv2 = SOCK_getservbyname((*argv)[1],"udp");
  727.     if (serv || serv2) {
  728.         if (FindPort("inetd")) {
  729. #if 0 /* I think this isn't needed, SOCK_inherit should be enough */
  730.         char daemon[MAXPATHLEN];
  731.         char line[1024];
  732.         char protocol[MAXPATHLEN];
  733.         FILE *inetdconf;
  734.         int founddaemon = 0;
  735.         if (inetdconf = fopen("inet:db/inetd.conf","r")) {
  736.             while (!feof(inetdconf)) {
  737.             fgets(line,sizeof(line),inetdconf);
  738.             sscanf(line,"%s %*s %*s %*s %s",protocol,daemon);
  739.             if (!strcmp(protocol,(*argv)[1])) {
  740.                 founddaemon = 1;
  741.                 break;
  742.             }
  743.             }
  744.             fclose(inetdconf);
  745.  
  746.             if (founddaemon)  {
  747.             char *filename = FilePart(daemon);
  748. #endif
  749.             if (/*!stricmp((*argv)[0],filename)*/1) {
  750.                 struct file *fp;
  751.             long sock_arg;
  752.             int sock;
  753.                 int i;
  754.  
  755.                 sock_arg = atol((*argv)[2]);
  756.                 p->sock_id = atoi((*argv)[3]);
  757.                 sock = SOCK_inherit((void *)sock_arg);
  758.                 if (sock != -1) {
  759.                 p->u_daemon = 1; /* I was started from inetd */
  760.                 do {
  761.                     fd = 0;
  762.                     if ((err = falloc(&fp, &fd)))
  763.                     break;
  764.  
  765.                     fp->f_so = sock;
  766.                     _set_socket_params(fp,AF_INET);
  767.  
  768.                     /* get rid of the args that AS225 put in */
  769.                     for (i=1; i < (*argc)-3; i++) {
  770.                     (*argv)[i] = (*argv)[i+3];
  771.                     }
  772.                     (*argc) -= 3;
  773.                 } while (0);
  774.  
  775.                 if (CURSIG (usr))
  776.                     SetSignal (0, SIGBREAKF_CTRL_C);
  777.                 }
  778.             }
  779. #if 0
  780.             }
  781.         }
  782. #endif
  783.         }
  784.     }
  785.     }
  786.     usr->p_stat = ostat;
  787.     errno = err;
  788.     return err ? -1 : fd;
  789. }
  790.  
  791. /* This is only needed for AS225 */
  792. void shutdown_inet_daemon(void)
  793. {
  794.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  795.     struct inetmsg inet_message;
  796.     struct MsgPort *msgport, *replyport;
  797.  
  798.     if (p->u_networkprotocol != IX_NETWORK_AS225 || !p->u_daemon)
  799.     return;
  800.  
  801.     if((inet_message.id = p->sock_id)) {
  802.     replyport = CreateMsgPort();
  803.     if(replyport) {
  804.         inet_message.msg.mn_Node.ln_Type = NT_MESSAGE;
  805.         inet_message.msg.mn_Length = sizeof(struct inetmsg);
  806.         inet_message.msg.mn_ReplyPort = replyport;
  807.  
  808.         msgport = FindPort("inetd");
  809.         if(msgport) {
  810.         PutMsg(msgport,(struct Message *)&inet_message);
  811.         /* we can't exit until we received a reply */
  812.         (void)WaitPort(replyport);
  813.         }
  814.         DeleteMsgPort(replyport);
  815.     }
  816.     }
  817. }
  818.  
  819.